#include "StdAfx.h"
#include "GdiObject.h"

using namespace Adaptive::Win32::Gdi;

/*--------------------------------------------------------------------------------
 * Constructor / Dispose / Destructor Methods
 *------------------------------------------------------------------------------*/
#pragma region Constructor / Dispose / Destructor Methods
// <summary>
// Initializes a new instance of the class.
// </summary>
// <param name="objectHandle">An <see cref="IntPtr"/> containing the handle.</param>
GdiObjectBase::GdiObjectBase(IntPtr objectHandle)
{
	_objectHandle = (HGDIOBJ)(objectHandle.ToInt32());
	_destroyFlag = false;
}
// <summary>
// Initializes a new instance of the class.
// </summary>
// <param name="objectHandle">An <see cref="IntPtr"/> containing the handle.</param>
// <param name="destroyWhenDone">A value indicating whether to destroy the handle when the instance is disposed.</param>
GdiObjectBase::GdiObjectBase(IntPtr objectHandle, bool destroyWhenDone)
{
	_objectHandle = (HGDIOBJ)(objectHandle.ToInt32());
	_destroyFlag = destroyWhenDone;
}
// <summary>	
// Initializes a new instance of the class.
// </summary>
// <param name="objectHandle">An <see cref="HGDIOBJ"/> containing the handle.</param>
// <param name="destroyWhenDone">A value indicating whether to destroy the handle when the instance is disposed.</param>
GdiObjectBase::GdiObjectBase(HGDIOBJ objectHandle, BOOL destroyWhenDone)
{
	_objectHandle = objectHandle;
	_destroyFlag = destroyWhenDone;
}
// <summary>
// Class destructor.
// </summary>
GdiObjectBase::~GdiObjectBase()
{
	if (!Disposed)
	{
		Delete();
		_objectHandle = NULL;
	}
}
#pragma endregion

/*--------------------------------------------------------------------------------
 * Public Properties
 *------------------------------------------------------------------------------*/
#pragma region Public Properties
// <summary>
// Gets a value indicating whether the object has been disposed.
// </summary>
// <value>
// <b>true</b> if the <see cref="Dispose()"/> method has already been called on the
// instance; otherwise, <b>false</b>.
// </value>
bool GdiObjectBase::IsValid::get()
{
	return (_objectHandle != NULL);
}
#pragma endregion

/*--------------------------------------------------------------------------------
 * Protected Methods / Event Methods
 *------------------------------------------------------------------------------*/
#pragma region Protected Methods / Event Methods
// Get object data.
int GdiObjectBase::GetObject( int sizeofData, array<Byte^>^ storageData)
{
	BYTE* memoryContent = NULL;
	LPVOID storagePtr = NULL;
	int returnValue = 0;
	int count = 0;

	//Create memory content.
	memoryContent = new BYTE[sizeofData];
	memset(memoryContent, 0, sizeofData);
	storagePtr = (LPVOID)memoryContent;

	returnValue = ::GetObject( _objectHandle, sizeofData, storagePtr );

	//Copy to outbound managed array.
	for (count = 0; count < sizeofData; count++)
		storageData[count] = (Byte)memoryContent[count];

	//Delete memory.
	delete[](memoryContent);
	memoryContent = NULL;
	storagePtr = NULL;

	return returnValue;

}
#pragma endregion

/*--------------------------------------------------------------------------------
 * Public Methods / Event Methods
 *------------------------------------------------------------------------------*/
#pragma region Public Methods / Event Methods
// Attach a handle to the current object.
void GdiObjectBase::Attach( IntPtr objectHandle, bool destroy)
{
	HGDIOBJ newHandle = NULL;

	//Convert.
	newHandle = (HGDIOBJ)(objectHandle.ToInt32());

	// Delete the current handle.
	Delete();

	// Setup the new handle.
	_objectHandle = newHandle;
	_destroyFlag   = (BOOL)destroy;
}
//
void GdiObjectBase::Delete()
{
	if ( _objectHandle && _destroyFlag )
		DeleteObject();
	else
		// Remove the handle.
		_objectHandle = NULL;

}
//
bool GdiObjectBase::DeleteObject()
{
	BOOL	result = FALSE;

	// Only destroy valid objects.
	if ( _objectHandle ) 
	{
		// Destroy the object.
		result = ::DeleteObject( _objectHandle );
	}

	// Clear handle.
	_objectHandle = NULL;

	// Return result.
	return (result > 0);
}
// Detach the wrapped handle.
IntPtr GdiObjectBase::Detach()
{
	IntPtr returnValue = IntPtr::Zero;

	returnValue = IntPtr::IntPtr(_objectHandle);
	_objectHandle = NULL;

	return returnValue;
}

GdiObjectBase::operator IntPtr()
{
	return IntPtr::IntPtr(_objectHandle);
}
#pragma endregion

/*--------------------------------------------------------------------------------
 * Private Event Handlers
 *------------------------------------------------------------------------------*/
#pragma region Private Event Handlers
#pragma endregion

